/*
 *  cam_fetch.cpp
 * Michael du Breuil
 */

#include "common.h"
#include "cam_fetch.h"
#include <unistd.h>
#include <time.h>

#define TIME_DELTA 5

cam_settings_t cam_settings;
int cam_continue;
pthread_mutex_t cam_mutex;
pthread_cond_t  cam_cond;

static int fetchCamera(cam_settings_t *settings, FILE *file) {
  CURL * curl;
  CURLcode result;

  curl = curl_easy_init();
  if(!curl) {
    fprintf(stderr, "ERROR: cam_init() curl failed to start");
    return FAILURE;
  }

  curl_easy_setopt(curl, CURLOPT_URL, settings->url);
  curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, NULL);
  curl_easy_setopt(curl, CURLOPT_WRITEDATA, file);

  result = curl_easy_perform(curl);

  curl_easy_cleanup(curl);

  if(result == CURLE_OK)
    return SUCCESS;
  else
    return FAILURE;

}

int cam_init() {
  pthread_mutex_init(&cam_mutex, NULL);
  pthread_mutex_lock(&cam_mutex);
  pthread_cond_init(&cam_cond, NULL);

  //build camera settings
  //strncpy(cam_settings.url, "http://192.168.1.115/image?res=full&x0=0&y0=0&x1=3648&y1=2752&quality=21&doublescan=0&ver=HTTP/1.1", sizeof(cam_settings.url));
  strncpy(cam_settings.url, "http://www.dopefish.com/images/sinefish.png", sizeof(cam_settings.url));
  cam_settings.rate       = 5;
  cam_settings.flags      = FLAG_PAUSE;

  pthread_mutex_unlock(&cam_mutex);

  return SUCCESS;
}

void cam_shutdown() {
  pthread_mutex_lock(&cam_mutex);

  cam_settings.flags = FLAG_PAUSE;

  pthread_cond_destroy(&cam_cond);
  pthread_mutex_unlock(&cam_mutex);
  pthread_mutex_destroy(&cam_mutex);
}

//main for camera thread
void *cam_run() {
  FILE *out;
  char outName[MAX_PATH];
  int success, i, sleepTime;
  clock_t t1, t2;

  i = 0;

  while(!(cam_settings.flags & FLAG_ABORT)) {
    pthread_mutex_lock(&cam_mutex);

    while(cam_settings.flags & FLAG_PAUSE) {
      pthread_cond_wait(&cam_cond, &cam_mutex);
    }

    t1 = clock();

    sprintf(outName, "images/out_%04d.jpg", i);
    out = fopen(outName, "wb");
    if(!out) {
      fprintf(stderr, "Failed to open image output\n");
      pthread_mutex_unlock(&cam_mutex);
      i++;
      continue;
    }
    success = fetchCamera(&cam_settings, out);
    fclose(out);

    if(success != SUCCESS) {
      fprintf(stderr, "ERROR: Could not fetch image #%d\n", i);
      unlink(outName);
    } else { //success so put it into the queue
      printf("Fetched image %d\n", i);
      pthread_mutex_lock(&image_mutex);
      if((image_tail >= MAX_QUEUED_IMAGES - 1 && image_head == 0) ||
           (image_tail + 1 == image_head)) {
        fprintf(stderr, "ERROR: Image queue was full, image #%d will not be automatically downloaded\n", i);
      } else {
        strncpy(images[image_tail].fileName, outName, MAX_PATH);
        strncpy(images[image_tail].gpsData, "NULL DATA", 32);
        images[image_tail].id = i;

        if(image_tail >= MAX_QUEUED_IMAGES - 1)
          image_tail = 0;
        else
          image_tail++;

      }

      //wake up anything that is waiting for images
      pthread_cond_broadcast(&image_cond);
      pthread_mutex_unlock(&image_mutex);
    }

    pthread_mutex_unlock(&cam_mutex);

    t2 = clock();

    //FIXME: this is a stupid amount of type conversion
    sleepTime = (int)((cam_settings.rate - ((double)(t2 -t1)) / CLOCKS_PER_SEC) * 1000000);
    if(sleepTime > 0)
	    usleep(sleepTime);
    else
      fprintf(stderr, "WANRING: cam_run() image #%d took longer than expected\n", i);

    i++;
  }

  pthread_exit(NULL);
}

